package myredis

import (
	"flag"
	"log"
	"time"
	"user-agent/utils"

	"github.com/gomodule/redigo/redis"
)

func newPool() *redis.Pool {
	config := utils.GetConfig().Redis
	return &redis.Pool{
		MaxIdle:     3,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", config.Url)
			if err != nil {
				return nil, err
			}
			if config.Auth != "" {
				if _, err := c.Do("AUTH", config.Auth); err != nil {
					c.Close()
					return nil, err
				}
			}
			if config.Db != "" {
				if _, err := c.Do("SELECT", config.Db); err != nil {
					c.Close()
					return nil, err
				}
			}
			return c, nil
		},
	}
}

var (
	pool *redis.Pool
)

func InitRedis() (conErr error) {
	flag.Parse()
	pool = newPool()
	conn := pool.Get()
	if err := conn.Err(); err != nil {
		conn.Close()
		log.Println("redis 连接失败")
		return err
	}
	log.Println("redis 连接成功")
	conn.Close()
	return nil
}

func GetRedis() *redis.Pool {
	return pool
}

func Keys(key string) ([]string, error) {
	conn := pool.Get()
	defer conn.Close()
	return redis.Strings(conn.Do("keys", key))
}

func Set(key string, value interface{}) (interface{}, error) {
	conn := pool.Get()
	defer conn.Close()
	return conn.Do("SET", key, value)
}

func Get(key string) (interface{}, error) {
	conn := pool.Get()
	defer conn.Close()
	return conn.Do("GET", key)
}

func Del(key string) error {
	conn := pool.Get()
	defer conn.Close()
	_, err := conn.Do("DEL", key)
	return err
}

func Exist(key string) (interface{}, error) {
	conn := pool.Get()
	defer conn.Close()
	return conn.Do("EXISTS", key)
}

func Incr(key string) {
	conn := pool.Get()
	defer conn.Close()
	conn.Do("INCR", key)
}

func HMSet(arg ...interface{}) {
	conn := pool.Get()
	defer conn.Close()
	conn.Do("HMSET", arg...)
}

func HIncr(key string, field string) {
	conn := pool.Get()
	defer conn.Close()
	conn.Do("HINCRBY", key, field, 1)
}

func SAdd(key string, value interface{}) {
	conn := pool.Get()
	defer conn.Close()
	conn.Do("SADD", key, value)
}

func SMembers(key string, dest interface{}) error {
	conn := pool.Get()
	defer conn.Close()
	values, err := redis.Values(conn.Do("SMEMBERS", key))
	if err != nil {
		return err
	}
	if err := redis.ScanSlice(values, dest); err != nil {
		return err
	}
	return nil
}

func SRem(key string, value interface{}) {
	conn := pool.Get()
	defer conn.Close()
	conn.Do("SREM", key, value)
}

func Sort(dest interface{}, key string, by string, arg ...interface{}) error {
	pool := GetRedis()
	conn := pool.Get()
	defer conn.Close()
	queue := make([]interface{}, 0)
	queue = append(queue, []interface{}{key, "BY", by}...)
	for _, value := range arg {
		queue = append(queue, "GET")
		queue = append(queue, value)
	}
	values, err := redis.Values(conn.Do("SORT", queue...))
	if err != nil {
		return err
	}
	if err := redis.ScanSlice(values, dest); err != nil {
		return err
	}
	return nil
}
